home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / unix / unz50p1.zoo / zipinfo.c < prev    next >
C/C++ Source or Header  |  1993-01-10  |  59KB  |  1,556 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   zipinfo.c
  4.  
  5.   This program reads all sorts of totally nifty information, including the
  6.   central directory stuff, from a ZIP archive ("zipfile" for short).  It
  7.   started as just a testbed for fooling with zipfiles, but at this point
  8.   it's actually a moderately useful utility.  It also became the basis
  9.   for the rewrite of unzip (3.16 -> 4.0), using the central directory for
  10.   processing rather than the individual (local) file headers.
  11.  
  12.   For myself, I find it convenient to define an alias "ii" (under Unix and
  13.   VMS) or to rename the executable to "ii.exe" (OS/2 and DOS).  This nicely
  14.   complements my Unix long-listing "ll" alias (ls -lF), since zipinfo's de-
  15.   fault action is to produce a Unix-like listing of the archive's contents.
  16.   "ii zipfile" is easier to type than "zipinfo zipfile"...
  17.  
  18.   Another dandy product from your buddies at Newtware!
  19.  
  20.   ---------------------------------------------------------------------------
  21.  
  22.   To compile (partial instructions; some of this stuff doesn't exist yet):
  23.  
  24.      under Unix (cc):  make zipinfo
  25.  
  26.      under MS-DOS (TurboC):  make -fMKZIPINF.DOS   (edit appropriately)
  27.  
  28.      under MS-DOS (MSC):  make MKZIPINF.DOS
  29.        (or use Makefile if you have MSC 6.0:  "nmake zi_dos")
  30.  
  31.      under OS/2 (MSC):  make MKZIPINF.DOS   (edit appropriately)
  32.        (or use Makefile if you have MSC 6.0:  "nmake zi_os2")
  33.  
  34.      under Atari OS:  beats me...
  35.  
  36.      under VMS:  @MAKE_ZIPINFO     (see also VMSNOTES)
  37.                  ZIPINFO == $DISKNAME:[DIRECTORY]ZIPINFO.EXE
  38.  
  39.      under Macintosh OS:  who knows?
  40.  
  41.   ---------------------------------------------------------------------------
  42.  
  43.   Source:     unz50p1.zip (.tar.Z, etc.) for Unix, VMS, OS/2 and MS-DOS; see
  44.               `Where' in source distribution for ftp, uucp and mail-server
  45.               sites.
  46.   Author:     Greg Roelofs, roelofs@nas.nasa.gov, 23 August 1990
  47.   Copyright:  Portions copyright 1992 Greg Roelofs.  Portions adapted from
  48.               unzip 3.1.  SizeOfEAs() by Kai Uwe Rommel.
  49.  
  50.   ---------------------------------------------------------------------------*/
  51.  
  52.  
  53.  
  54.  
  55. #ifndef ZIPINFO
  56. #  define ZIPINFO   /* needed for Unix permissions in non-Unix environments */
  57. #endif /* !ZIPINFO */
  58. #include "unzip.h"
  59.  
  60. #define VERSION  "v1.0p1 of 10 January 1993"
  61.  
  62. #define LFLAG    3        /* for short "ls -l" type listing */
  63.  
  64. #define EAID     0x0009   /* OS/2 EA extra field ID */
  65. typedef struct {          /* for OS/2 info in OS/2 and non-OS/2 environments */
  66.     unsigned short nID;
  67.     unsigned short nSize;
  68.     ULONG lSize;
  69. } EAHEADER, *PEAHEADER;
  70.  
  71.  
  72.  
  73.  
  74. /**********************/
  75. /*  Global Variables  */
  76. /**********************/
  77.  
  78. #ifdef EBCDIC
  79.    int  aflag=1;        /* this is so you can read it on the screen  */
  80. #else                   /* (basically, entire program is "unzip -c") */
  81.    int  aflag=0;
  82. #endif
  83. int lflag=(-1);         /* '-1slmv':  listing format */
  84. int hflag=0;            /* '-h':  header line */
  85. int tflag=0;            /* '-t':  totals line */
  86.  
  87. byte *inbuf, *inptr;    /* input buffer (any size is legal) and pointer */
  88. int incnt;
  89.  
  90. int zipfd;              /* zipfile file handle */
  91. char zipfn[FILNAMSIZ];
  92.  
  93. char local_hdr_sig[5] = "\120";    /* remaining signature bytes come later:  */
  94. char central_hdr_sig[5] = "\120";  /*  must initialize at runtime so zipinfo */
  95. char end_central_sig[5] = "\120";  /*  executable won't look like a zipfile  */
  96. char extd_local_sig[5] = "\120";
  97.  
  98. cdir_file_hdr crec;             /* used in zipinfo.c, misc.c */
  99. local_file_hdr lrec;
  100. ecdir_rec ecrec;
  101. struct stat statbuf;            /* used by main() */
  102.  
  103. int process_all_files;
  104. longint real_ecrec_offset, expect_ecrec_offset;
  105. longint extra_bytes=0;          /* used in zipinfo.c, misc.c */
  106. longint cur_zipfile_bufstart;   /* find_end_central_dir, readbuf */
  107.  
  108. min_info info, *pInfo=(&info);
  109.  
  110. byte *extra_field = NULL;       /* used by VMS, Mac and OS/2 versions */
  111. byte *outbuf;                   /* buffer for rle look-back, zipfile comment */
  112. byte *outout;                   /* scratch pad for ASCII-native trans */
  113.  
  114. char filename[FILNAMSIZ];
  115. char sig[5];
  116. char *fnames[2] = {"*", NULL};    /* default filenames vector */
  117. char **fnv = fnames;
  118.  
  119. static byte *hold;
  120. static longint ziplen;
  121. static UWORD hostnum;
  122. static UWORD methnum;
  123. static UWORD extnum;
  124.  
  125. char *EndSigMsg = "\nwarning:\
  126.   didn't find end-of-central-dir signature at end of central dir.\n";
  127. char *CentSigMsg =
  128.   "error:  expected central file header signature not found (file #%u).\n";
  129. char *SeekMsg =
  130.   "error:  attempt to seek before beginning of zipfile\n%s";
  131.  
  132. #ifdef VMS
  133. char *ReportMsg = "\
  134.   (please check that you have transferred or created the zipfile in the\n\
  135.   appropriate BINARY mode--this includes ftp, Kermit, AND unzip'd zipfiles)\n";
  136. #else /* !VMS */
  137. char *ReportMsg = "\
  138.   (please check that you have transferred or created the zipfile in the\n\
  139.   appropriate BINARY mode and that you have compiled unzip properly)\n";
  140. #endif /* ?VMS */
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147. /******************/
  148. /*  Main program  */
  149. /******************/
  150.  
  151. main(argc, argv)
  152.     int    argc;
  153.     char   *argv[];
  154. {
  155.     char   *s;
  156.     int    c, error=FALSE, negative=0;
  157.     int    hflag_slmv=TRUE, hflag_1=FALSE;  /* diff options => diff defaults */
  158.     int    tflag_slm=TRUE, tflag_1v=FALSE;
  159.     int    explicit_h=FALSE, explicit_t=FALSE;
  160.  
  161.  
  162.  
  163. /*---------------------------------------------------------------------------
  164.     Everybody is now "NOTINT16," but this is a nice little piece of code, so
  165.     just comment it out for future reference. :-)
  166.   ---------------------------------------------------------------------------*/
  167.  
  168. #if 0
  169. # ifndef KNOW_IT_WORKS  /* define this to save space, if things already work */
  170. # ifndef DOS_OS2        /* already works (no RISCy OS/2's yet...) */
  171. # ifndef NOTINT16       /* whole point is to see if this NEEDS defining */
  172.     {
  173.         int error=0;
  174.         long testsig;
  175.         static char *mach_type[3] = {"big-endian", "structure-padding",
  176.                                      "big-endian and structure-padding"};
  177.  
  178.         strcpy((char *)&testsig,"012");
  179.         if (testsig != 0x00323130)
  180.             error = 1;
  181.         if (sizeof(cdir_file_hdr) != CREC_SIZE)
  182.             error += 2;
  183.         if (error--)
  184.             fprintf(stderr, "It appears that your machine is %s.  If errors\n\
  185. occur, please try recompiling with \"NOTINT16\" defined (read the\n\
  186. Makefile, or try \"make zipinfo\").\n\n", mach_type[error]);
  187.     }
  188. # endif /* !NOTINT16 */
  189. # endif /* !DOS_OS2 */
  190. # endif /* !KNOW_IT_WORKS */
  191. #endif /* 0 */
  192.  
  193. /*---------------------------------------------------------------------------
  194.     Put environment-variable options into the queue, then rip through any
  195.     command-line options lurking about...
  196.   ---------------------------------------------------------------------------*/
  197.  
  198.     envargs(&argc, &argv, ENV_ZIPINFO);
  199.  
  200.     while (--argc > 0 && (*++argv)[0] == '-') {
  201.         s = argv[0] + 1;
  202.         while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
  203.             switch (c) {
  204.                 case '-':
  205.                     ++negative;
  206.                     break;
  207.                 case '1':      /* shortest listing:  just filenames */
  208.                     if (negative)
  209.                         lflag = -2, negative = 0;
  210.                     else
  211.                         lflag = 1;
  212.                     break;
  213.                 case 'h':      /* header line */
  214.                     if (negative)
  215.                         hflag_1 = hflag_slmv = FALSE, negative = 0;
  216.                     else {
  217.                         hflag_1 = hflag_slmv = explicit_h = TRUE;
  218.                         if (lflag == -1)
  219.                             lflag = 0;
  220.                     }
  221.                     break;
  222.                 case 'l':      /* longer form of "ls -l" type listing */
  223.                     if (negative)
  224.                         lflag = -2, negative = 0;
  225.                     else
  226.                         lflag = 5;
  227.                     break;
  228.                 case 'm':      /* medium form of "ls -l" type listing */
  229.                     if (negative)
  230.                         lflag = -2, negative = 0;
  231.                     else
  232.